package com.example.socket.server;

import com.example.socket.codec.MessageCodecFactory;
import com.example.socket.filter.FilterHandler;
import com.example.socket.filter.session.SessionManager;
import com.example.socket.filter.session.SessionManagerFilter;
import com.example.socket.handler.NettyHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.concurrent.EventExecutorGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * CHANNEL 初始化
 * @author Ramon
 */
public class ServerHandlerInitializer extends ChannelInitializer<SocketChannel> {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private ChannelHandler handler;
    private List<FilterHandler> filters;
    private EventExecutorGroup executor;

    private MessageCodecFactory codecFactory = new MessageCodecFactory();
    private SessionManagerFilter defaultSessionManager = new SessionManagerFilter();

    ServerHandlerInitializer(NettyHandler handler, ExecutorService executor, SessionManager sessionManager,
                             List<FilterHandler> filters) {
        this.handler = (ChannelHandler) handler;
        this.executor = (EventExecutorGroup) executor;
        this.defaultSessionManager.setSessionManager(sessionManager);
        this.filters = filters;
    }

    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // 编码解码器
        pipeline.addLast("DECODER", codecFactory.getDecoder(Short.MAX_VALUE));
        pipeline.addLast("ENCODER", codecFactory.getEncoder());
        // 过滤器
        for (FilterHandler filterHandler : filters) {
            String key = filterHandler.getName();
            ChannelHandler value = (ChannelHandler) filterHandler;
            try {
                if (pipeline.get(key) != null) {
                    logger.error("Handler>>>>[{}]重复已忽略!", key);
                    continue;
                }
                pipeline.addLast(key, value);
                if (logger.isDebugEnabled()) {
                    logger.debug("连接[{}]添加过滤器[{}]", ch.remoteAddress(), key);
                }
            } catch (Exception ex) {
                logger.error("连接[{}]添加过滤器异常!", ch.remoteAddress(), ex);
                throw ex;
            }
        }
        // 处理器
        pipeline.addLast(executor, "HANDLER", handler);
    }
}
